﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using PSE.ProcessManager.Server.Process;
using System.Threading;
//using PSE.ProcessManager.Common.Logging;
using System.IO;
using System.Configuration;
using System.Reflection;
using PSE.Framework.ErrorLogging;
using PSE.ProcessManager.Common.Process;
using PSE.Framework.Process;
using PSE.Framework.Configuration;

namespace PSE.ProcessManager.Server.Process.Executor
{
    class Program : BaseProgram
    {
        private const string CONFIGFILENAME = ConfigurationManager.ConfigurationManager.EXECUTOR_CONFIG;
        private static int _processId;

        static Program()            
        {
            Initialize(PSE.Framework.Configuration.Components.SystemComponents.System, PSE.Framework.Configuration.Components.SystemComponents.Process);
        }

        /// <summary>
        /// Recebe como parametro:
        /// args[8] - Caminho do diretorio de configuracao da instancia
        /// args[9] - Assembly path
        /// args[10] - Class full name
        /// </summary>
        /// <param name="args"></param>
        static int Main(string[] args)
        {
            try
            {
                if (args.Length != 11)
                    throw new ArgumentNullException("Arguments not found.");
                else
                {
                    string executorConfigFile = args[8] + @"\" + CONFIGFILENAME;

                    if (!File.Exists(executorConfigFile))
                        throw new ArgumentException("Argument not valid.", "Executor Config File");

                    string assemblyPath = args[9];
                    if (string.IsNullOrEmpty(assemblyPath))
                        throw new ArgumentException("Argument not valid.", "Assembly Path");

                    string classFullName = args[10];
                    if (string.IsNullOrEmpty(classFullName))
                        throw new ArgumentException("Argument not valid.", "Class Full Name");

                    //Implementacao para tornar MULTI-PRODUTO
                    //Criar um appDomain para subir a instancia do executor, possibilitando dessa forma informar um config especifico para cada
                    //produto/instancia 
                    AppDomainSetup domainSetup = new AppDomainSetup();
                    domainSetup.ApplicationBase = AppDomain.CurrentDomain.SetupInformation.ApplicationBase;
                    domainSetup.ApplicationName = AppDomain.CurrentDomain.SetupInformation.ApplicationName;
                    domainSetup.ConfigurationFile = executorConfigFile;

                    AppDomain executorDomain = AppDomain.CreateDomain("ServerProcessExecutor", null, domainSetup);

                    ProcessExecutor executor = (ProcessExecutor)executorDomain.CreateInstanceAndUnwrap(Assembly.GetExecutingAssembly().FullName, "PSE.ProcessManager.Server.Process.Executor.ProcessExecutor");
                    bool ret = executor.Run(assemblyPath, classFullName, args);

                    Thread.Sleep(5000);

                    return ret ? 0 : 1;
                }
            }
            catch (Exception ex)
            {
                HandleException(ex);
                return 1;
            }
        }
    }
}
